﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Tedds_Tool.Automatables;
using LEET.Utilities;

namespace LEET.DynamicLoading
{
    public class LEETLoader
    {
        public static IEnumerable<Type> LoadAll<T>()
        {
            AppDomain domain = AppDomain.CurrentDomain;
            // Note: assemblies are loaded as needed. So in order to have dynamic loading work
            // we must force loading of all dlls in the imediate app directory
            try
            {
                foreach (FileInfo info in Helpers.FilesFromDir(new DirectoryInfo("."), false))
                {
                    if (".dll".Equals(info.Extension))
                    {
                        AssemblyName name = AssemblyName.GetAssemblyName(info.FullName);
                        domain.Load(name);
                    }
                }
            }
            catch (Exception e)
            {
                ;
            }

            List<Assembly> assemblies = domain.GetAssemblies().ToList<Assembly>();
            assemblies.Sort(new AssemblyComparison());

            IEnumerable<Type> types1 = assemblies.SelectMany(new Func<Assembly, IEnumerable<Type>>(delegate(Assembly s) 
            {
                try
                {
                    return s.GetTypes();
                }
                catch
                {
                    return new List<Type>();
                }
            }));
            IEnumerable<Type> types = types1.Where(delegate(Type w){
                try
                {
                    return 
                        typeof(T).IsAssignableFrom(w)
                        && w != typeof(T)
                        ;
                } catch {
                    return false;
                }
            });
            return types;
        }
    }

    class AssemblyComparison : IComparer<Assembly>
    {
        public int Compare(Assembly x, Assembly y)
        {
            return x.FullName.CompareTo(y.FullName);
        }
    }
}
